#include <iostream>
#include <apr_getopt.h>
#include "GBGwServer.h"
#include "SDLog.h"
#include "ini.h"
//#include "server.h"

#define LOG_TAG "Main"
#define SECTION_CONFIG							   "Config"
#define SECTION_SIP							       "Sip"
#define KEY_NAME_REDIS_PORT		                   "Port.Redis"
#define KEY_NAME_REDIS_IP		                   "Ip.Redis"
#define KEY_NAME_MEDIA_INTERNAL_IP		           "Ip.MediaServer.Internal"
#define KEY_NAME_MEDIA_INTERNAL_PORT		       "Port.MediaServer.Internal"
#define KEY_NAME_UPPER_EXTERNAL_IP		           "Ip.Sip.Upper.External"
#define KEY_NAME_UPPER_EXTERNAL_PORT		       "Port.Sip.Upper.External"
#define KEY_NAME_UPPER_EXTERNAL_DOMAIN		       "Domain.Sip.Upper"
#define KEY_NAME_UPPER_REG_INTERVAL		           "Interval.Reg.Sip.Upper"
#define KEY_NAME_UPPER_KEEPALIVE_INTERVAL		   "Interval.Keepalive.Sip.Upper"
#define KEY_NAME_MY_SIP_USERNAME		           "Username.Sip"
#define KEY_NAME_MY_SIP_PASSWORD		           "Password.Sip"
#define KEY_NAME_MY_SIP_PORT		               "Port.Sip.Internal"
#define KEY_NAME_GB28181_CITY		               "GB28181.City"
#define DEFAULT_CONFIG_PATH                        "gbrelaysvr.ini"

static std::mutex g_lock;
static std::condition_variable g_cond;

const apr_getopt_option_t g_cmd_option[] = {
    {"config",'c',TRUE,"config filename"},
    {"help",'h',FALSE,"show help information"},
    {nullptr,0,0,nullptr},
};
#define GUANGZHOU
int main(int argc, const char *argv[])
{
    std::string config_path;
    struct GBRelayConfig config;

    apr_initialize();
    CSDLog_Init("./log",SD_LOG_LEVEL_DEBUG,NULL);
    //SDLOG_PRINTF(LOG_TAG,SD_LOG_LEVEL_ALARM, "Ver:%d.%d Patch:%d Build:%s",BUILD_MAJOR_VERSION,BUILD_MINOR_VERSION,BUILD_PATCH_VERSION,BUILD_AT);

    {
        int opt_ch;
        apr_getopt_t *opt;
        const char *opt_arg;
        apr_pool_t *pool;
        apr_pool_create(&pool, nullptr);
        apr_getopt_init(&opt,pool,argc,argv);
        while( APR_SUCCESS == apr_getopt_long(opt,g_cmd_option,&opt_ch,&opt_arg))
        {
            switch(opt_ch)
            {
                case 'c':
                    config_path = std::string(opt_arg);
                    break;
                case 'h':
                    break;
                default:
                    break;
            }
        }
        if(config_path.empty()){
            config_path = DEFAULT_CONFIG_PATH;
            std::cout <<"config path not specified,use default" << endl;
        }
        apr_pool_destroy(pool);
    }

    {
        std::string value;
        miniINI::INIFile file(config_path);
        miniINI::INIStructure ini;
        file.read(ini);
        memset(&config,sizeof(config),0);

#define GET_STRING_VALUE(SECTION,KEY,FIELD,DEFAULT) \
        value = ini[SECTION][KEY];        \
        if(value.length() > 0){           \
            snprintf(FIELD,sizeof(FIELD),"%s",value.c_str());\
        }  else {                                   \
           snprintf(FIELD,sizeof(FIELD),"%s",DEFAULT); \
           ini[SECTION][KEY] = DEFAULT;      \
        }

#define GET_INT_VALUE(SECTION,KEY,FIELD,DEFAULT) \
        value = ini[SECTION][KEY];        \
        if(value.length()){               \
            (FIELD) = atoi(value.c_str());  \
        } else {                          \
           FIELD = atoi(DEFAULT);\
           ini[SECTION][KEY] = DEFAULT;   \
        }
        GET_STRING_VALUE(SECTION_CONFIG,KEY_NAME_REDIS_IP,config.redis_ip,"172.16.1.50");
        GET_INT_VALUE(SECTION_CONFIG,KEY_NAME_REDIS_PORT,config.redis_port,"6000");
        GET_STRING_VALUE(SECTION_CONFIG,KEY_NAME_MEDIA_INTERNAL_IP,config.inner_media_ip,"125.69.0.100");
        GET_INT_VALUE(SECTION_CONFIG,KEY_NAME_MEDIA_INTERNAL_PORT,config.inner_media_port,"30003");
        /*
          53010001      03            132          5       000000
          34020000      00            200          5       100010
          中心编码(8)  行业编码（2）  类型编码(3)  网络标识(1) 序列号(6)
        */
        //GET_STRING_VALUE(SECTION_CONFIG,KEY_NAME_GB28181_CITY,config.gb28281_serial,"53010001031325");

#ifdef DAHUA
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_UPPER_EXTERNAL_IP,config.upper_server_ip,"127.0.0.1");
        GET_INT_VALUE(SECTION_SIP,KEY_NAME_UPPER_EXTERNAL_PORT,config.upper_server_port,"5060");
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_UPPER_EXTERNAL_DOMAIN,config.upper_server_domain,"34020000001180000001");
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_MY_SIP_USERNAME,config.sip_username,"43000000801328000001");
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_MY_SIP_PASSWORD,config.sip_password,"12345678");
#elif defined(FUJIAN)
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_UPPER_EXTERNAL_IP,config.upper_server_ip,"120.36.3.109");
        GET_INT_VALUE(SECTION_SIP,KEY_NAME_UPPER_EXTERNAL_PORT,config.upper_server_port,"5060");
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_UPPER_EXTERNAL_DOMAIN,config.upper_server_domain,"34020000002000000001");
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_MY_SIP_USERNAME,config.sip_username,"34020000002005100000");
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_MY_SIP_PASSWORD,config.sip_password,"34020000002005100000");
#elif defined(GUANGZHOU)
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_UPPER_EXTERNAL_IP,config.upper_server_ip,"183.63.70.123");
        GET_INT_VALUE(SECTION_SIP,KEY_NAME_UPPER_EXTERNAL_PORT,config.upper_server_port,"35060");
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_UPPER_EXTERNAL_DOMAIN,config.upper_server_domain,"43100000032001001203");
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_MY_SIP_USERNAME,config.sip_username,"43000000801328000001");
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_MY_SIP_PASSWORD,config.sip_password,"12345678");
#else
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_UPPER_EXTERNAL_IP,config.upper_server_ip,"192.168.0.111");
        GET_INT_VALUE(SECTION_SIP,KEY_NAME_UPPER_EXTERNAL_PORT,config.upper_server_port,"5060");
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_UPPER_EXTERNAL_DOMAIN,config.upper_server_domain,"34020000001180000001");
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_MY_SIP_USERNAME,config.sip_username,"43000000801328000001");
        GET_STRING_VALUE(SECTION_SIP,KEY_NAME_MY_SIP_PASSWORD,config.sip_password,"12345678");
#endif
        GET_INT_VALUE(SECTION_SIP,KEY_NAME_UPPER_REG_INTERVAL,config.upper_reg_interval,"60");
        GET_INT_VALUE(SECTION_SIP,KEY_NAME_UPPER_KEEPALIVE_INTERVAL,config.upper_refresh_interval,"3");
        GET_INT_VALUE(SECTION_SIP,KEY_NAME_MY_SIP_PORT,config.inner_sip_port,"35070");


        file.write(ini);

        std::cout <<"redis_ip:" << config.redis_ip  << std::endl
        <<",redis_port:"<< config.redis_port << std::endl
        << ",inner_media_ip:" << config.inner_media_ip  << std::endl
        << ",inner_media_port:" << config.inner_media_port  << std::endl
        << ",upper_server_ip:" << config.upper_server_ip  << std::endl
        << ",upper_server_port:" << config.upper_server_port  << std::endl
        << ",upper_server_domain:" << config.upper_server_domain  << std::endl
        << ",upper_reg_interval:" << config.upper_reg_interval  << std::endl
        << ",upper_refresh_interval:" << config.upper_refresh_interval  << std::endl
        << ",sip_username:" << config.sip_username  << std::endl
        << ",sip_password:" << config.sip_password  << std::endl
        << ",inner_sip_port:" << config.inner_sip_port
        << std::endl;

        auto server = std::make_shared<GBGwServer>();
        server->startServer(config);
        {
            std::unique_lock<std::mutex> lck(g_lock);
            g_cond.wait(lck);
            server->stopServer();
        }
    }

    auto server = new GBGwServer();
    if(!server) {
        goto FAILED;
    }
    server->startServer(config);
    {
        std::unique_lock<std::mutex> lck(g_lock);
        g_cond.wait(lck);
    }
    if(server)
        delete server;
FAILED:
    CSDLog_Close();
    apr_terminate();
    return 0;
}
